const commands = require('../commands/tspl')
const { strToByteArray } = require('../printerutil')
const wximage = require('../../../utils/lib/wxImg')

const TSPL_OPTIONS_DEFAULT = {
  charset: 'gb2312'
}

const PrinterTspl = function (options) {
  this._opts = Object.assign(TSPL_OPTIONS_DEFAULT, options);
  this._queue = [];
  this._enqueue = function (cmd) {
    this._queue.push.apply(this._queue, cmd);
  }
};

/**
 * 该指令用于设定标签纸的宽度及高度
 * This command defines the label width and length.<br>
 * SIZE m mm,n mm<br>
 * @param m ,Label width (inch/ mm/ dot)
 * @param n ,Label length (inch/ mm/ dot)
 * @return this
 * */
PrinterTspl.prototype.sizeBymm = function (m, n) {
  var cmd = strToByteArray(commands.SIZE.MM_M_N.format(m, n), this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * 该指令定义两张标签纸间的垂直间距距离
 * Defines the gap distance between two labels<br>.
 * GAP m,n<br>
 * @param m,The gap distance between two labels<br>
 * 0 ≤ m ≤1 (inch), 0 ≤ m ≤ 25.4 (mm)<br>
 * 0 ≤ m ≤5 (inch), 0 ≤ m ≤ 127 (mm) / since V6.21 EZ and later firmware<br>
 * 	@param n,The offset distance of the gap<br>
 * n ≤ label length (inch or mm)		<br>
 * @return this
 * */
PrinterTspl.prototype.gapBymm = function (m, n) {
  var cmd = strToByteArray(commands.GAP.MM_M_N.format(m, n), this._opts.charset);
  this._enqueue(cmd)
  return this;
};

	/**
	 * 该指令用于设定黑标的高度及偏移位置
	 * This command sets the height of the black line and the user-defined extra label feeding length each
	 * form feed takes.<br>
	 * BLINE m dot,n dot <br>
	 * @param m  The height of black line either in inch or mm<br>
	 * 0 ≤ m ≤ 1 (inch), 0 ≤ m ≤ 25.4 (mm)<br>
	 * 0 ≤ m ≤5 (inch), 0 ≤ m ≤ 127 (mm) / since V6.21 EZ and later firmware<br>
	 * @param n  The extra label feeding length<br>
	 * 0 ≤ n ≤ label length<br>
	 * @return byte[]
	 * */
  PrinterTspl.prototype.blineBymm = function (m, n) {
    var cmd = strToByteArray(commands.BLINE.MM_M_N.format(m, n), this._opts.charset);
    this._enqueue(cmd)
    return this;
  };

/**
 * 该指令用于定义打印时出纸的方向
 * This command defines the printout direction and mirror image. This will be stored in the printermemory.<br>
 * DIRECTION n[,m]<br>
 * @param n  0 or 1.<br>
 * @return this
 * */
PrinterTspl.prototype.direction = function (n) {
  var cmd = strToByteArray(commands.DIRECTION_N.format(n), this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * This command sets the printing darkness<br>
 * DENSITY n<br>
 * @param n  0~15<br>
 * 0: specifies the lightest level<br>
 * 15: specifies the darkest level<br>
 * @return byte[]
 * */
PrinterTspl.prototype.density = function (n) {
  var cmd = strToByteArray(commands.DENSITY_N.format(n), this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * 该指令用于清除影像缓冲区(image buffer)的资料<br>
 * This command clears the image buffer.<br>
 * CLS<br>
 * @return this
 * */
PrinterTspl.prototype.cls = function (n) {
  var cmd = strToByteArray(commands.CLS, this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * 使用該指令時，打印機將立即裁切<br>
 * This command activates the cutter to immediately cut the labels without back feeding the label.<br>
 * CUT<br>
 * @return byte[]
 * */
PrinterTspl.prototype.cut = function (n) {
  var cmd = strToByteArray(commands.CLS, this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * At this command, the printer will print out the printer information<br>
 * SELFTEST [page]<br>
 * @return byte[]
 * */
PrinterTspl.prototype.selftest = function (n) {
  var cmd = strToByteArray(commands.SELFTEST, this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * This command prints text on label.<br>
 * 打印一段文字<br>
 * TEXT x,y,”font”,rotation,x-multiplication,y-multiplication,”content”<br>
 * @param 	x  The x-coordinate of the text<br>
 * 	@param		y  The y-coordinate of the text<br>
 * 	@param		font  Font name请参考编程手册<br>
 * 	@param		rotation  The rotation angle of text<br>
            0 : No rotation<br>
            90 : degrees, in clockwise direction<br>
            180 : degrees, in clockwise direction<br>
            270 : degrees, in clockwise direction<br>
  @param		x_multiplication  Horizontal multiplication, up to 10x<br>
  @param		y_multiplication  Vertical multiplication, up to 10x<br>
      
  @param		content  Content of text string<br>
  @return byte[]
  * */
PrinterTspl.prototype.text = function (x, y, font, rotation, x_multiplication, y_multiplication, content) {
  var cmd = strToByteArray(commands.TEXT_X_Y_FONT_ROTATION_XMULTIPLICATION_YMULTIPLICATION_CONTENT
    .format(x,y,font,rotation,x_multiplication,y_multiplication,content), this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * 在标签上画线<br>
 * This command draws a bar on the label format.<br>
 * BAR x,y,width,height<br>
 * @param x  The upper left corner x-coordinate (in dots)<br>
 * @param y  The upper left corner y-coordinate (in dots)<br>
 * @param width  Bar width (in dots)<br>
 * @param height  Bar height (in dots)<br>
 * @return byte[]
 * */
PrinterTspl.prototype.bar = function (x,y,width,height) {
  var cmd = commands.BAR_X_Y_WIDTH_HEIGHT.format(x,y,width,height);
  cmd = strToByteArray(cmd, this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * 該指令用來畫一維條螞，共計 23 種<br>
 * 详细注解请查看编程手册<br>
 * This command prints 1D barcodes. The available barcodes are listed below:<br>
 * BARCODE X,Y,”codetype”,height,humanreadable,rotation,narrow,wide,[alignment,]”content “<br>
 * @return this
 * */
PrinterTspl.prototype.barCode = function (x,y,codeType,height,human,rotation,narrow,wide,content) {
  var cmd = commands.BARCODE_X_Y_CODETYPE_HEIGHT_HUMAN_ROTATION_NARROW_WIDE_CONTENT
  .format(x,y,codeType,height,human,rotation,narrow,wide,content);
  cmd = strToByteArray(cmd, this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * 该指令用来画二维码<br>
 * 详细注解请查看编程手册<br>
 * This command prints 2D barcodes.<br>
 * QRCODE x,y,ECC Level,cell width,mode,rotation,[model,mask,]"content"<br>
 * @return this
 * */
PrinterTspl.prototype.qrcode = function (x,y,eccLevel,cellWidth,mode,rotation,model,mask,content) {
  var cmd = commands.QRCODE_X_Y_ECCLEVEL_CELLWIDTH_MODE_ROTATION_MODEL_MASK_CONTENT.format(x,y,eccLevel,cellWidth,mode,rotation,model,mask,content);
  cmd = strToByteArray(cmd, this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * 该指令用来画光栅位图<br>
 * @param 	x  The x-coordinate of the text<br>
 * @param		y  The y-coordinate of the text<br>
 * @param		mode  图像格式: 
 *                0: OVERWRITE
 *                1: OR
 *                2: XOR
 * @param  imageData  图像原始数据
 * @return this
 * */
PrinterTspl.prototype.bitmap = function (x,y,mode,imgData) { //参数，画布的参数
  let imgs = new wximage();
	// imgs.SetRGB(wxRect(0, 0, 400, 600), 255, 255, 255);
  let img = imgs.overwriteImageData(imgData)
  let width = img.width
  let height = img.height
  let cmdStart = "BITMAP " + x + "," + y + "," + width + "," + height + "," + mode + ",";
  let cmdEnd = "\n";
  cmdStart = strToByteArray(cmdStart, this._opts.charset)
  cmdEnd = strToByteArray(cmdEnd, this._opts.charset)
  this._enqueue(cmdStart)
  this._enqueue(img.array)
  this._enqueue(cmdEnd)

  console.log('printImage cmd:', this._queue)
  return this;
};

/**
 * 该指令用于打印出储存于图像缓冲区的资料<br>
 * This command prints the label format currently stored in the image buffer.<br>
 * PRINT m [,n]<br>
 * @param 	m  Specifies how many sets of labels will be printed.1 ≤ m ≤ 999999999
 * @param   n  Specifies how many copies should be printed for each particular label set.1 ≤ n ≤ 999999999
 * @return byte[]
 * */
PrinterTspl.prototype.print = function (m) {
  var cmd = strToByteArray(commands.PRINT_M.format(m), this._opts.charset);
  this._enqueue(cmd)
  return this;
};

/**
 * 返回ArrayBuffer
 */
PrinterTspl.prototype.buffer = function () {
  return new Uint8Array(this._queue).buffer;
};

module.exports = PrinterTspl;